package com.cskaoyan.pointcut;

import com.cskaoyan.bean.bo.AuthLoginBo;
import com.cskaoyan.bean.pojo.Log;
import com.cskaoyan.bean.pojo.admin.Admin;
import com.cskaoyan.dao.AdminMapper;
import com.cskaoyan.dao.LogMapper;
import com.cskaoyan.utils.IpUtil;
import lombok.SneakyThrows;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.Date;

/**
 * @author: thz
 * @class: SystemPointcut
 */
@Aspect
@Component
public class SystemPointcut {

    @Autowired
    AdminMapper adminMapper;

    @Autowired
    LogMapper logMapper;

    @Pointcut("execution(* com..SystemController.admin*(..))")
    public void pointcut() {
    }

    @Pointcut("execution(* com..backgroundsystemcontroller.AuthController.*Log*(..))")
    public void pointcut1() {
    }

    @SneakyThrows
    @Around("pointcut()")
    public Object adminMethodAround(ProceedingJoinPoint joinPoint) {
        Log log = new Log();
        Object[] args = joinPoint.getArgs();

        Object admin = args[0];
        Field field = admin.getClass().getDeclaredField("username");
        field.setAccessible(true);
        String result = (String) field.get(admin);

        HttpServletRequest request = (HttpServletRequest) args[1];
        String ip = IpUtil.getUserIp(request);

        Subject subject = SecurityUtils.getSubject();
        Admin primaryPrincipal = (Admin) subject.getPrincipals().getPrimaryPrincipal();
        log.setAdmin(primaryPrincipal.getUsername());

        Signature signature = joinPoint.getSignature();
        String action = signature.getName();
        if (action.endsWith("Update")) {
            log.setAction("编辑管理员");
        } else if (action.endsWith("Delete")) {
            log.setAction("删除管理员");
        } else if (action.endsWith("Create")) {
            log.setAction("添加管理员");
        }


        log.setIp(ip);
        log.setResult(result);
        log.setAddTime(new Date());
        log.setUpdateTime(new Date());
        log.setComment("");
        log.setStatus(true);
        log.setType(1);
        logMapper.insertSelective(log);
        Object proceed = joinPoint.proceed();
        return proceed;
    }

    @SneakyThrows
    @Around("pointcut1()")
    public Object adminLogMethodAround(ProceedingJoinPoint joinPoint) {

        Log log = new Log();
        Object[] args = joinPoint.getArgs();

        HttpServletRequest request = (HttpServletRequest) args[0];
        String ip = IpUtil.getUserIp(request);

        Signature signature = joinPoint.getSignature();
        String action = signature.getName();

        Object proceed = null;

        if (action.endsWith("Login")) {
            proceed = joinPoint.proceed();
            Field field = proceed.getClass().getDeclaredField("errmsg");
            field.setAccessible(true);
            String msg = (String) field.get(proceed);
            log.setAction("登录");
            if ("成功".equals(msg)) {
                AuthLoginBo authLoginBo = (AuthLoginBo) args[1];
                log.setAdmin(authLoginBo.getUsername());
                log.setStatus(true);
            } else {
                log.setAdmin("匿名用户");
                log.setStatus(false);
                log.setResult(msg);
            }
        } else if (action.endsWith("Logout")) {
            Subject subject = SecurityUtils.getSubject();
            Admin primaryPrincipal = (Admin) subject.getPrincipals().getPrimaryPrincipal();
            log.setAdmin(primaryPrincipal.getUsername());
            proceed = joinPoint.proceed();
            log.setAction("退出");
            log.setStatus(true);
        }

        log.setIp(ip);
        log.setAddTime(new Date());
        log.setUpdateTime(new Date());
        log.setComment("");
        log.setType(1);

        logMapper.insertSelective(log);
        return proceed;
    }
}
